#ifndef     __LOG_UART_H
#define     __LOG_UART_H

#include "../utils/nocopyable.h"
#include "../utils/object.h"
#include "../rtos/message_queue.h"
#include "../rtos/event_flags.h"
#include <stdint.h>
#include "../utils/byte_view.h"
#include "../utils/error.h"

namespace driver {

class LogUart_t : private utils::NoCopyable_t {

public:
    static const uint32_t WriteFlag = 0x01;
    static const uint32_t TxFlag = 0x02;

    LogUart_t();

    utils::Error_t recv_proto(utils::ByteView_t &bw);

    void printf(const char *format, ...);

    void write(const uint8_t *buf, uint32_t size);

    void write_ack();

    void write_uint8(uint16_t req, uint8_t val);

    void recv_byte(uint8_t byte);

    inline void tx_signal() {
        m_flags.set_flags(TxFlag);
    }

private:
    void write_impl(const uint8_t *buf, uint32_t size);

    inline void tx_clear() {
        m_flags.clr_flags(TxFlag);
    }
    inline void tx_wait() {
        m_flags.wait_any(TxFlag);
    }

    inline void write_lock() {
        m_flags.wait_any(WriteFlag);
    }
    inline void write_unlock() {
        m_flags.set_flags(WriteFlag);
    }

    bool next_uint16(uint16_t &val);

    inline bool next_byte(uint8_t &val) {
        return osOK == m_mq.poll(val, 10);
    }

    rtos::MessageQueue_t<uint8_t, 100> m_mq;
    rtos::EventFlags m_flags;

    uint8_t m_tx_buf[100];
};

extern utils::Object<LogUart_t> logUart;

}



#endif
